package cn.dduan.fool.design.pattern.behavior.visitor;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 访问者模式
 *
 * @author dduan
 * @version 1.0
 * @date 2023/4/10
 */
public class VisitorPattern {
    public static void main(String[] args) {
        Medicine a = new MedicineA("板蓝根", 11.0);
        Medicine b = new MedicineB("感康", 14.3);

        Presciption presciption = new Presciption();
        presciption.addMedicine(a);
        presciption.addMedicine(b);

        Visitor charger = new Charger();
        charger.setName("张三");

        Visitor workerOfPharmacy = new WorkerOfPharmacy();
        workerOfPharmacy.setName("李四");

        presciption.accept(charger);
        System.out.println("-------------------------------------");
        presciption.accept(workerOfPharmacy);

    }
}

/**
 * 抽象访问者
 *
 * @author dduan
 * @version 1.0
 * @date 2023/4/10
 */
abstract class Visitor {
    protected String name;

    public void setName(String name) {
        this.name = name;
    }

    public abstract void visitor(MedicineA a);

    public abstract void visitor(MedicineB b);
}

/**
 * 具体实现：划价员
 *
 * @author dduan
 * @version 1.0
 * @date 2023/4/10
 */
class Charger extends Visitor {

    @Override
    public void visitor(MedicineA a) {
        System.out.println("划价员：" + name + "给药" + a.getName() + "划价:" + a.getPrice());
    }

    @Override
    public void visitor(MedicineB b) {
        System.out.println("划价员：" + name + "给药" + b.getName() + "划价:" + b.getPrice());
    }
}

/**
 * 具体实现：药房工作者
 *
 * @author dduan
 * @version 1.0
 * @date 2023/4/10
 */
class WorkerOfPharmacy extends Visitor {

    @Override
    public void visitor(MedicineA a) {
        System.out.println("药房工作者：" + name + "拿药 ：" + a.getName());
    }

    @Override
    public void visitor(MedicineB b) {
        System.out.println("药房工作者：" + name + "拿药 ：" + b.getName());
    }
}

/**
 * 抽象元素
 *
 * @author dduan
 * @version 1.0
 * @date 2023/4/10
 */
abstract class Medicine {
    protected String name;
    protected double price;

    public Medicine(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public abstract void accept(Visitor visitor);
}

/**
 * 具体实现：元素A
 *
 * @author dduan
 * @version 1.0
 * @date 2023/4/10
 */
class MedicineA extends Medicine {

    public MedicineA(String name, double price) {
        super(name, price);
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visitor(this);
    }
}

/**
 * 具体实现：元素B
 *
 * @author dduan
 * @version 1.0
 * @date 2023/4/10
 */
class MedicineB extends Medicine {

    public MedicineB(String name, double price) {
        super(name, price);
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visitor(this);
    }
}

/**
 * 药单
 *
 * @author dduan
 * @version 1.0
 * @date 2023/4/10
 */
class Presciption {
    List<Medicine> list = new ArrayList<Medicine>();

    public void accept(Visitor visitor) {
        Iterator<Medicine> iterator = list.iterator();

        while (iterator.hasNext()) {
            iterator.next().accept(visitor);
        }
    }

    public void addMedicine(Medicine medicine) {
        list.add(medicine);
    }

    public void removeMedicien(Medicine medicine) {
        list.remove(medicine);
    }
}